import 'package:floor/floor.dart';
import 'package:flutter/foundation.dart';
import 'package:share_fit/app/models/base_model.dart';
import 'package:share_fit/app/tools/date_tool.dart';

@Entity(tableName: 'sports')
class SportsModel extends BaseModel {
  ///单次运动记录 ID
  @ColumnInfo(name: 'record_id')
  int? recordId;

  /// 单次运动状态, 1:完成 2:未完成
  int? status;

  /// 起始时间
  @ColumnInfo(name: 'start_time')
  int? startTime;

  /// 结束时间
  @ColumnInfo(name: 'end_time')
  int? endTime;

  /// 卡路里，单位：千卡
  int? calorie;

  /// 距离，单位：米
  int? distance;

  /// 步数
  int? step;

  /// 总时长，单位：秒
  @ColumnInfo(name: 'total_time')
  int? totalTime;

  /// 平均速度，单位：dm/s
  int? speed;

  /// 平均配速
  int? pace;

  /// 步幅
  int? stride;

  /// 爬高高度差：单位（分米）
  int? climb;

  /// 心率
  int? heart;

  /// 心率最小值
  @ColumnInfo(name: 'hr_abs_min_peak')
  int? hrAbsMinPeak;

  /// 心率最大值
  @ColumnInfo(name: 'hr_abs_max_peak')
  int? hrAbsMaxPeak;

  /// 运动效果
  @ColumnInfo(name: 'training_effect')
  int? trainingEffect;

  /// 最大耗氧量
  @ColumnInfo(name: 'oxygen_consumption')
  int? oxygenConsumption;

  /// MET
  @ColumnInfo(name: 'oxygen_uptake')
  int? oxygenUptake;

  /// 完全恢复时长
  @ColumnInfo(name: 'recovery_time')
  int? recoveryTime;

  /// 活动时间：秒
  int? duration;

  /// 单次运动类型，具体见 WorkoutType
  @ColumnInfo(name: 'workout_type')
  int? workoutType;

  /// ete 算法类型
  @ColumnInfo(name: 'alg_type')
  int? algType;

  /// 跳绳最大连跳数
  @ColumnInfo(name: 'longest_streak')
  int? longestStreak;

  /// 跳绳拌绳数
  @ColumnInfo(name: 'tripped_count')
  int? trippedCount;

  /// 脂肪消耗，单位：千卡
  @ColumnInfo(name: 'fat_consumption')
  int? fatConsumption;

  /// 脂肪占比，[0-100]
  @ColumnInfo(name: 'fat_percentage')
  int? fatPercentage;

  /// 脂肪估算重量，单位：mg
  @ColumnInfo(name: 'fat_weight')
  int? fatWeight;

  /// 体能年龄
  @ColumnInfo(name: 'fitness_age')
  int? fitnessAge;

  ///
  @ColumnInfo(name: 'lowest_altitude')
  int? lowestAltitude;

  ///
  @ColumnInfo(name: 'highest_altitude')
  int? highestAltitude;

  /// 上楼层数
  @ColumnInfo(name: 'floors_up')
  late int? floorsUp;

  /// 下楼层数
  @ColumnInfo(name: 'floors_down')
  late int? floorsDown;

  /// 拉桨时间 单位 秒
  @ColumnInfo(name: 'pull_time')
  late int? pullTime;

  /// 收桨时间 单位 秒
  @ColumnInfo(name: 'free_time')
  late int? freeTime;

  SportsModel({
    super.address,
    super.dateCreated,
    super.dateModified,
    this.recordId,
    this.status,
    this.startTime,
    this.endTime,
    this.calorie,
    this.distance,
    this.step,
    this.totalTime,
    this.speed,
    this.climb,
    this.hrAbsMinPeak,
    this.hrAbsMaxPeak,
    this.trainingEffect,
    this.oxygenConsumption,
    this.oxygenUptake,
    this.recoveryTime,
    this.duration,
    this.workoutType,
    this.algType,
    this.longestStreak,
    this.trippedCount,
    this.fatConsumption,
    this.fatPercentage,
    this.fatWeight,
    this.fitnessAge,
    this.lowestAltitude,
    this.highestAltitude,
    this.floorsUp,
    this.floorsDown,
    this.pullTime,
    this.freeTime,
    this.pace,
    this.heart,
    this.stride,
  });

  /// 一下3种条件不会保存运动记录<br/><br/>
  ///
  /// 1.运动距离小于200米<br/>
  /// 2.运动时长小于一分钟<br/>
  /// 3.热量小于2千卡
  bool isInvalidRealRecord() {
    if (kDebugMode) {
      return ((distance ?? 0) / 10) < 5 || ((calorie ?? 0) ~/ 1000) < 0 || (duration ?? 0) < 5;
    }
    return ((distance ?? 0) / 10) < 200 || ((calorie ?? 0) ~/ 1000) < 2 || (duration ?? 0) < 60;
  }

  /// 一下3种条件不会保存运动记录<br/><br/>
  ///
  /// 1.运动距离小于200米<br/>
  /// 2.运动时长小于一分钟<br/>
  /// 3.热量小于2千卡
  bool isInvalidFromReportRecord() {
    if (kDebugMode) {
      return (distance ?? 0) < 5 || (calorie ?? 0) < 0 || (duration ?? 0) < 5;
    }
    return (distance ?? 0) < 200 || (calorie ?? 0) < 2 || (duration ?? 0) < 60;
  }

  /// 换算长度单位
  getRealTimeDistanceText(int unit) {
    /// 分米转成公里
    double temp = (distance ?? 0) / 10 / 1000;
    if (unit == 1) {
      temp = temp * 0.62137;
    }
    return temp <= 0 ? '--' : temp.toStringAsFixed(2);
  }

  /// 换算长度单位
  get getDistanceText {
    double temp = ((distance ?? 0) / 1000);
    return temp <= 0 ? '' : temp.toStringAsFixed(2);
  }

  /// 将秒转换成00:00:00格式
  String get getDurationText {
    return duration == null ? '00:00:00' : DateTool.second2HMS(duration!);
  }

  String get getHeartText {
    return heart == null || heart == 0 ? '--' : '$heart';
  }

  String get getPaceText {
    var ms = '00\'00"';
    if (pace != null && pace! > 0) {
      int m = pace! ~/ 60;
      int s = pace! % 60;
      ms = "$m'$s\"";
    }
    return ms;
  }

  String get getCalorieText {
    return calorie == null || calorie == 0 ? '--' : '${calorie! ~/ 1000}';
  }

  bool fromRealTime(Map map) {
    try {
      calorie = map['calorie'];
      distance = map['distance'];
      duration = map['duration'];
      pace = map['pace'];
      if (map.containsKey('heartRate')) {
        heart = map['heartRate'];
      } else {
        heart = map['heart'];
      }
      return true;
    } catch (e) {
      return false;
    }
  }

  @override
  bool from(Map map) {
    try {
      recordId = map['recordId'];
      status = map['status'];
      startTime = map['startTime'];
      endTime = map['endTime'];
      calorie = map['calorie'];
      distance = map['distance'];
      duration = map['duration'];
      step = map['step'] ?? 0;
      pace = map['avgPace'];
      stride = map['stride'];
      totalTime = map['totalTime'];
      speed = map['speed'];
      climb = map['climb'];
      hrAbsMinPeak = map['hrAbsMinPeak'];
      hrAbsMaxPeak = map['hrAbsMaxPeak'];
      trainingEffect = map['trainingEffect'];
      oxygenConsumption = map['oxygenConsumption'];
      oxygenUptake = map['oxygenUptake'];
      recoveryTime = map['recoveryTime'];
      workoutType = map['workoutType'];
      algType = map['algType'];
      longestStreak = map['longestStreak'];
      trippedCount = map['trippedCount'];
      fatConsumption = map['fatConsumption'];
      fatPercentage = map['fatPercentage'];
      fatWeight = map['fatWeight'];
      fitnessAge = map['fitnessAge'];
      lowestAltitude = map['lowestAltitude'];
      highestAltitude = map['lowestAltitude'];
      floorsUp = map['floorsUp'];
      floorsDown = map['floorsDown'];
      pullTime = map['pullTime'];
      freeTime = map['freeTime'];
      return true;
    } catch (e) {
      return false;
    }
  }

  @override
  List<Object?> get props => [
        recordId,
        status,
        startTime,
        endTime,
        calorie,
        distance,
        step,
        totalTime,
        speed,
        pace,
        stride,
        climb,
        heart,
        hrAbsMinPeak,
        hrAbsMaxPeak,
        trainingEffect,
        oxygenConsumption,
        oxygenUptake,
        recoveryTime,
        duration,
        workoutType,
        algType,
        longestStreak,
        trippedCount,
        fatConsumption,
        fatPercentage,
        fatWeight,
        fitnessAge,
        lowestAltitude,
        highestAltitude,
        floorsUp,
        floorsDown,
        pullTime,
        freeTime,
      ];

  @override
  bool? get stringify => true;
}
